#pragma once
#include <iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include "Connection.hpp"
#include "Log.hpp"
// 只负责IO
class HandleConnection
{
public:
    HandleConnection()
    {
    }
    HandleConnection(handler_t process)
    {
        _pocess = process;
    }
    ~HandleConnection()
    {
    }
    void _handler_recever(Connection *conn)
    {
        // LOG(DEBUG, "_handler_recever,client:%d\n", conn->Sockfd());
        // 读取数据,读取所有一次性发送的数据
        errno = 0;
        char buff[1024];
        while (true)
        {
            int n = ::recv(conn->Sockfd(), buff, 1023, 0);
            if (n > 0)
            {
                buff[n] = 0;//数据块，不断加载到conn的缓冲区
                std::string buffer(buff);
                conn->SetInbufffer(buffer);
            }
            else
            {
                if(errno ==EWOULDBLOCK)//读取完毕,无数据可读
                {
                    LOG(DEBUG,"读取完毕\n");
                    break;
                }
                else if(errno == EINTR)//信号中断
                {
                    LOG(DEBUG,"信号中断\n");
                    continue;
                }
                else{
                    LOG(DEBUG,"读取异常\n");
                    conn->_handler_excepter(conn);//处理异常
                    return;
                }
            }
        }
      printf("_handler_recever,client:%d,data:%s\n", conn->Sockfd(),conn->GetInbuffer().c_str());
      //
      _pocess(conn);

    }
    void _handler_sender(Connection *conn)
    {
        //一次性发完
        errno = 0;
        while(true)
        {
            ssize_t n = ::send(conn->Sockfd(),conn->GetOutbuffer().c_str(),conn->GetOutbuffer().size(),0);
            if(n > 0)//实际发送了多少数据
            {
                conn->DiscardOutbuffer(n);//删除已经发送的数据
                if(conn->GetOutbuffer().empty())//发送完毕
                {
                    break;//向上返回
                }
            }
            else if(n == 0)
            {
                break;

            }
            else
            {
                //tcp发送缓冲区写满
                if(errno == EWOULDBLOCK)
                {
                    break;//向下break
                }
                //被信号在终端
                else if(errno == EINTR ) continue;
                //发送失败
                else
                {
                    conn->_handler_excepter(conn);//处理异常
                    return;
                }
            }
        } 
        //此时发送缓冲区写满了,需要继续发送
        if(!conn->GetOutbuffer().empty())
        {
            //将写事件打透到epoll
            conn->_R->EnableConnectionReadWritr(conn->Sockfd(),true,true);
        }
        else
        {
            conn->_R->EnableConnectionReadWritr(conn->Sockfd(),true,false);

        }


    }
    void _handler_excepter(Connection *conn)
    {
        LOG(DEBUG,"处理异常\n");
        conn->_R->RemoveConnection(conn->Sockfd());
    }
private:
    handler_t _pocess;
};